﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Reflection;
using Studio.Network.Utilities;
using System.Text;
using Studio.Network.Kaixin001;
using Studio.Foundation.Text;

namespace Studio.Network.Kaixin001
{
    public class KXRegister
    {
        HttpHelper http = new HttpHelper();

        public static readonly string URL_KX_BASE = "http://www.kaixin001.com/";

        public static readonly string URL_KX_HOME = "http://www.kaixin001.com/home/";

        public static readonly string URL_KX_REG_SUBMIT = URL_KX_BASE + "reg/reg_submit.php?" +
            "email={0}&email2={0}&password={1}&password2={1}&real_name={2}&gender=1&year=2008&month=01&day=01&" +
            "city=上海&status=0&company=&school=&baseinfoprivacy=1&code={3}&rcode={4}&" +
            "usercode={5}";

        public static readonly string URL_KX_REG_MAIL = URL_KX_BASE + "reg/reg_mail.php?email={0}";

        public static readonly string URL_KX_LOGIN = URL_KX_BASE + "login/login.php?email={0}&password={1}";

        public static readonly string URL_KX_APP_HOME = URL_KX_BASE + "app/app.php?aid={0}";

        private string usercode = string.Empty;

        private string inviteUrl = string.Empty;

        public string UserCode
        {
            get { return usercode; }
            set { usercode = value; }
        }

        private string email;

        public string Email
        {
            get { return email; }
            set { email = value; }
        }
        private string password;

        public string Password
        {
            get { return password; }
            set { password = value; }
        }


        public KXRegister(string email, string password)
        {
            this.email = email;
            this.password = password;
            this.Initialize();        
        }

        public KXRegister()
        {
            this.Initialize();
        }

        public void Initialize()
        {
            http.Timeout = 5000;
            http.ResponseEncoding = Encoding.UTF8;
            http.RequestEncoding = Encoding.UTF8;
        }

        public static string[] MAP_DIGITAL_CHARACTER = { "玲", "依", "儿", "璨", "丝", "舞", "柳", "琪", "贝", "玫" };
        public static string[] MAP_DIGITAL_FAMILY = { "赵", "钱", "孙", "李", "周", "吴", "郑", "王", "冯", "陈" };

        // public static string[] MAP_DIGITAL_FAMILY = { "石", "白", "尔", "王", "斯", "吴", "刘", "戚", "毕", "秋" };

        public int UId
        {
            get
            {
                if (false == this.Login())
                    return -1;
                else
                {
                    string home = this.HomePage;
                    home = StringUtilities.Cut(home, "ID:", "\"");
                    int uid;
                    return int.TryParse(home, out uid) ? uid : 0;
                }
            }
        }

        // realname //-1/0/1/2 -- 未验证/合法/非法/违禁
        // email	//-1/0/1/2 -- 未验证/可用/注册未验证/注册已验证
        // code 	//-1/0/1 -- 未验证/非法/合法


        public static readonly string URL_KX_APP_INSTALL = "http://www.kaixin001.com/app/install.php?aid={0}&isinstall=1";

        public static readonly string URL_KX_NEW_FRIEND = URL_KX_BASE + "friend/addverify.php/?from=&touid={0}&content={1}";
        public static readonly string URL_KX_NEW_FRIEND_REFER = URL_KX_BASE + "friend/new.php?touid={0}";

        public static readonly string URL_KX_CHANGE_PASSWORD = URL_KX_BASE + "/set/passwd_submit.php?old={0}&password={1}&password2={1}";
        public static readonly string URL_KX_CHANGE_PASSWORD_REFER = URL_KX_BASE + "set/passwd.php";
        /**
        <FORM name=editform action=/friend/editfriend.php method=post>
        <INPUT type=hidden value=8321767 name=fuid>
        <INPUT type=hidden name=byname> 
        <INPUT type=hidden name=memo>
        <INPUT type=hidden value=现在同事,其他 name=groups>
        <INPUT type=hidden value=现在同事,以前同事,大学同学,高中同学,家人亲戚,挚交好友,普通朋友,朋友的朋友,其他,上海交大 name=allgroups>
        <INPUT type=hidden value=0 name=start>
        <INPUT type=hidden value=sysmsg name=from> 
        <INPUT type=hidden value=731399110 name=smid>
        </FORM>
        */

        public static readonly string URL_KX_EDIT_FRIEND = URL_KX_BASE + "friend/editfriend.php/?fuid={0}&byname=&" +
                "memo=&groups=&allgroups=&start=0&from=sysmsg&smid={1}";


        public static readonly string[] KEY_SYS_MSG_DIVIDERS = new string[] { "<div class=\"l srr_tt\">", "title=\"清空系统消息" };
        public static readonly string KEY_LOGIN_FAILED = "帐号或密码不太对吧";
        public static readonly string KEY_SYS_MSG_FRIEND_REQUEST = "好友请求";

        public static readonly string URL_KX_SYS_MSG = URL_KX_BASE + "msg/sys.php?start={0}";

        public static string Naming(int number)
        {
            string name;
            number = number % 1000;
            name = MAP_DIGITAL_FAMILY[number / 100];
            number = number % 100;
            name += MAP_DIGITAL_CHARACTER[number / 10];
            number = number % 10;
            return name + MAP_DIGITAL_CHARACTER[number];
        }


        /// <summary>
        /// Read Register Code only.
        /// </summary>
        public Image RegisterCode
        {
            get
            {
                // read code. set time out first
                int timeout = http.Timeout;
                http.Timeout = 5000;
                Image codeImage = http.GetImage(string.Format(KXInterface.URL_KX_CODE, KXInterface.RAND));
                http.Timeout = timeout;
                return (null == codeImage) ? Properties.Resources.Wrong : codeImage;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="inviteUrl"></param>
        /// <param name="isRisk">Read RegisterCode without invite</param>
        /// <returns></returns>
        public Image InviteRegisterCode(string inviteUrl)
        {
            // No invitation, No Code
            if (false == inviteUrl.Contains("usercode"))
            {
                return Properties.Resources.Wrong;
            }
            else if (string.IsNullOrEmpty(this.usercode))
            {
                // Extract usercode
                this.usercode = StringUtilities.Cut(inviteUrl, "usercode=", "&");
                this.inviteUrl = inviteUrl;
                //http.GET(inviteUrl);
            }
            return this.RegisterCode;
        }

        public string Register(string email, string realname, string password, string code)
        {
            // string url = string.Format(URL_KX_REG_SUBMIT, email, password, realname, KXRegister.CODE, KXRegister.RAND, "");
            string url = string.Format(URL_KX_REG_SUBMIT, email, password, realname, code, KXInterface.RAND, usercode);
            string response = http.POST(url, this.inviteUrl);
            System.Diagnostics.Debug.WriteLine(response);
            return response;
        }

        public static string RegisterEmail(string email)
        {
            HttpHelper installer = new HttpHelper();
            string url = string.Format(URL_KX_REG_MAIL, email);
            string response = installer.POST(url);
            System.Diagnostics.Debug.WriteLine(response);
            return response;
        }

        private bool isLogin = false;

        public bool IsLogin
        {
            get { return isLogin; }
        }

        public bool Login()
        {
            return this.Login(false);
        }

        private string HomePage
        {
            get
            {
                return this.Login() ? http.POST(URL_KX_HOME) : this.LoginFailed;
            }
        }

        public bool Login(bool reLogin)
        {
            if (false == isLogin && false == reLogin)
            {
                string url = string.Format(URL_KX_LOGIN, email, password);
                string response = http.POST(url);
                bool succeed = (false == response.Contains(KEY_LOGIN_FAILED));
                this.isLogin = succeed;
            }
            return this.isLogin;
        }

        public string NewFriend(int uid, string content)
        {
            if (true == this.Login())
            {
                string url = string.Format(URL_KX_NEW_FRIEND, uid, content);
                string refer = string.Format(URL_KX_NEW_FRIEND_REFER, uid);
                string response = http.POST(url, refer);
                System.Diagnostics.Debug.WriteLine(response);
                return response;
            }
            else
            {
                return this.LoginFailed;
            }
        }

        public string EditFriend(int fuid)
        { 
            int i;
            return this.EditFriend(fuid, out i);
        }

        /// <summary>
        /// Edit a friend, This will be done by searching a friend request smid by ourself.
        /// </summary>
        /// <param name="fuid"></param>
        /// <returns></returns>
        public string EditFriend(int fuid, out int smid)
        {
            smid = 0;
            // Login first
            if(false == this.Login())
                return this.LoginFailed;
            // try to find one sysmsg
            string[] msgs = this.ReadSysMSG(0);
            foreach (string msg in msgs)
            {
                if (msg.Contains(KEY_SYS_MSG_FRIEND_REQUEST) &&
                    msg.Contains(string.Format("/home/?uid={0}", fuid)))
                    smid = this.ParseSMId(msg);
                // parse succeed ?
                if (0 < smid) break;
            }
            return EditFriend(fuid, smid);
        }

        private int ParseSMId(string msg)
        {
            msg = StringUtilities.Cut(msg, "smid=", "&");
            int smid;
            if (false == int.TryParse(msg, out smid))
                return 0;
            return smid;
        }

        public string[] ReadSysMSG(int start)
        {
            string [] EMPTY = new string[] { };
            if (false == this.Login())
                return EMPTY;
            else
            {
                string url = string.Format(URL_KX_SYS_MSG, start);
                string response = http.POST(url);
                string[] divisions = response.Split(KEY_SYS_MSG_DIVIDERS, StringSplitOptions.RemoveEmptyEntries);
                // First and Last division are useless
                if (2 >= divisions.Length)
                    return EMPTY;
                // copy to result
                string[] msgs = new string[divisions.Length - 2];
                for (int i = 1; i < divisions.Length - 1; i++)
                    msgs[i - 1] = divisions[i];
                return msgs;
            }
        }

        public string EditFriend(int fuid, int smid)
        {
            if (true == this.Login())
            {
                string url = string.Format(URL_KX_EDIT_FRIEND, fuid, smid);
                string response = http.POST(url);
                System.Diagnostics.Debug.WriteLine(response);
                return response;
            }
            else
            {
                return this.LoginFailed;
            }
        }

        public string LoginFailed
        {
            get { return string.Format("Account {0}:{1} Login failed.", this.email, this.password); }
        }

        public static bool Install(string email, string password, KXApplication app)
        {
            return KXRegister.Install(email, password, app.AppId);
        }

        private static bool Install(string email, string password, int appId)
        {
            HttpHelper installer = new HttpHelper();
            string url = string.Format(URL_KX_LOGIN, email, password);
            string response = installer.POST(url);
            url = string.Format(URL_KX_APP_INSTALL, appId);
            response = installer.POST(url);
            System.Diagnostics.Debug.WriteLine(response);
            return response.Contains(string.Format(URL_KX_APP_HOME, appId));
        }

        public string ChangePassword(string newPassword)
        {
            if (true == this.Login())
            {
                string url = string.Format(URL_KX_CHANGE_PASSWORD, this.password, newPassword);
                string response = http.POST(url, URL_KX_CHANGE_PASSWORD_REFER);
                System.Diagnostics.Debug.WriteLine(response);
                return response;
            }
            else
            {
                return this.LoginFailed;
            }
        }
    }
} 
